﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;

namespace SendEmailCustomerService
{
    public class MainCore
    {
        public static log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public string connectstring = ConfigurationSettings.AppSettings["connectstring"];


        public void MainFunctionSendEmail()
        {
            var recipient = ConfigurationSettings.AppSettings["ContactSupportEmail"];
            var bcc = ConfigurationSettings.AppSettings["BccContactSupportEmail"];

            var ds = dta_GetListCustomer();
            logger.Info("Number of customers : " + ds.Rows.Count);

            foreach (DataRow row in ds.Rows)
            {
                SendContactEmail(new SendContactCommand() { Email = row["Email"].ToString(), Message = "", Name = "", Recipient = recipient, BccRecipient = bcc });
            }

        }

        public DataTable dta_GetListCustomer()
        {
            SqlConnection sqlConn = new SqlConnection(connectstring);
            SqlCommand sqlCmd = new SqlCommand();
            try
            {
                sqlConn.Open();
                sqlCmd.CommandType = CommandType.StoredProcedure;
                sqlCmd.CommandText = "GetListCustomerEmail";
                sqlCmd.Connection = sqlConn;
                SqlDataAdapter adapter = new SqlDataAdapter(sqlCmd);
                DataSet ds = new DataSet();
                (new DynamicallyNameTableAdapter()).FillFromReader(ds, adapter.SelectCommand);
                if (ds != null && ds.Tables.Count > 0)
                {
                    return ds.Tables["Customers"];
                }
            }
            catch (Exception ex)
            {
                logger.Error("Open Connection Error : " + ex.Message);
            }
            finally
            {
                sqlCmd.Dispose();
                sqlConn.Close();
                sqlConn.Dispose();
            }
            return null;
        }

        public void SendContactEmail(SendContactCommand command)
        {
            //Guard.ArgumentIsNotNull(command, "command");
            //Guard.ArgumentIsNotNull(command.Email, "email");
            //Guard.ArgumentIsNotNull(command.Name, "name");
            //Guard.ArgumentIsNotNull(command.Message, "message");
            //Guard.ArgumentIsNotNull(command.Recipient, "recipient");
            var email = BuildContactEmail(command.Recipient, command.BccRecipient, command.Name, command.Email, command.Message);
            SendEmail(email);
        }

        public void SendEmail(MailMessage mailMessage, bool isBodyHtml = true)
        {
            if (mailMessage.To.Count < 1)
            { }
            //throw new ValidationException("MailMessage object must contain at least an address where you want to send the message.");
            mailMessage.IsBodyHtml = isBodyHtml;
            var client = new SmtpClient();
            client.Send(mailMessage);
        }

        private MailMessage BuildContactEmail(string recipient, string bcc, string name, string emailAddress, string message)
        {
            var mailBody = TranslateMergeField(Resources.Content.ContactBody, name, emailAddress, message);
            var mailSubject = TranslateMergeField(Resources.Content.ContactHeader, name, emailAddress, message);

            var email = new MailMessage();
            email.To.Add(new MailAddress(recipient));
            if (!string.IsNullOrWhiteSpace(bcc))
            {
                email.Bcc.Add(bcc);
            }
            email.Subject = mailSubject;
            email.Body = mailBody;
            email.IsBodyHtml = true;
            return email;
        }

        private string TranslateMergeField(string body, string name, string email, string message)
        {
            var result = body.Replace("{Contact_Email}", email).Replace("{Contact_Name}", name).Replace("{Contact_Message}", message);
            return result;
        }
    }
}

public sealed class DynamicallyNameTableAdapter : DataAdapter
{
    public int FillFromReader(DataSet set, DbCommand command)
    {
        int count = 0;
        using (DbDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.KeyInfo))
        {
            do
            {
                DataTable table = null;
                string tableName = (reader.GetSchemaTable().Rows[0][SchemaTableColumn.BaseTableName] as string);
                if (!String.IsNullOrEmpty(tableName))
                {
                    table = set.Tables[tableName];
                }
                if (null == table)
                {
                    table = new DataTable(tableName);
                    set.Tables.Add(table);
                }

                count += Fill(new DataTable[] { table }, reader, 0, 0);
            } while (reader.NextResult());
        }
        return count;
    }
}
